﻿using static System.Net.Mime.MediaTypeNames;
using System.Diagnostics;
using System.Drawing;
using Image = System.Drawing.Image;
using Font = System.Drawing.Font;
using System.Drawing.Imaging;
using SkiaSharp;

namespace ShuiyinSkiaSharpDemo02
{
    internal class Program
    {
        #region 自动创建图片 加水印 然后删除原始图片
        //static async Task Main(string[] args)
        //{
        //    string inputDirectory = "input_images"; // 输入图片目录
        //    string outputDirectory = "output_images"; // 输出图片目录

        //    // 创建输入和输出目录
        //    Directory.CreateDirectory(inputDirectory);
        //    Directory.CreateDirectory(outputDirectory);

        //    // 启动模拟图片生成任务
        //    var imageGeneratorTask = Task.Run(() => SimulateImageGeneration(inputDirectory));

        //    // 启动图片处理任务
        //    var imageProcessorTask = Task.Run(() => ProcessImagesAsync(inputDirectory, outputDirectory));

        //    // 等待任务完成（这里会一直运行，直到手动停止程序）
        //    await Task.WhenAll(imageGeneratorTask, imageProcessorTask);
        //}

        //// 模拟图片生成的方法
        //static void SimulateImageGeneration(string inputDirectory)
        //{
        //    int imageCounter = 0;

        //    while (true)
        //    {
        //        // 每隔 1 秒生成一批图片
        //        Thread.Sleep(1000);

        //        // 生成 10 张图片
        //        for (int i = 0; i < 10; i++)
        //        {
        //            string imagePath = Path.Combine(inputDirectory, $"image_{imageCounter++}.jpg");
        //            CreateSampleImage(imagePath);
        //            Console.WriteLine($"生成图片: {imagePath}");
        //        }
        //    }
        //}

        //// 创建一张示例图片
        //static void CreateSampleImage(string imagePath)
        //{
        //    using (var bitmap = new SKBitmap(800, 600))
        //    using (var canvas = new SKCanvas(bitmap))
        //    {
        //        // 填充背景色
        //        canvas.Clear(SKColors.LightGray);

        //        // 保存图片
        //        using (var image = SKImage.FromBitmap(bitmap))
        //        using (var data = image.Encode(SKEncodedImageFormat.Jpeg, 100))
        //        using (var stream = File.OpenWrite(imagePath))
        //        {
        //            data.SaveTo(stream);
        //        }
        //    }
        //}

        //// 异步处理图片的方法
        //static async Task ProcessImagesAsync(string inputDirectory, string outputDirectory)
        //{
        //    while (true)
        //    {
        //        // 获取输入目录中的所有图片文件
        //        var imageFiles = Directory.GetFiles(inputDirectory, "*.jpg");

        //        // 并行处理每张图片
        //        var tasks = imageFiles.Select(imageFile =>
        //            Task.Run(() => ProcessSingleImageAsync(imageFile, outputDirectory)));

        //        await Task.WhenAll(tasks);

        //        // 每隔 1 秒检查一次新图片
        //        await Task.Delay(1000);
        //    }
        //}

        //// 异步处理单张图片的方法
        //static async Task ProcessSingleImageAsync(string inputPath, string outputDirectory)
        //{
        //    await Task.Run(() =>
        //    {
        //        // 加载原始图片
        //        using (var originalImage = SKBitmap.Decode(inputPath))
        //        {
        //            // 创建一个画布
        //            using (var canvas = new SKCanvas(originalImage))
        //            {
        //                // 设置水印文本
        //                string watermarkText = $"Watermark {Path.GetFileName(inputPath)}";

        //                // 创建画笔
        //                var paint = new SKPaint
        //                {
        //                    Color = SKColors.White.WithAlpha(128), // 设置颜色和透明度
        //                    TextSize = 48, // 设置字体大小
        //                    IsAntialias = true, // 启用抗锯齿
        //                    Typeface = SKTypeface.FromFamilyName("Arial", SKFontStyle.Bold) // 设置字体
        //                };

        //                // 计算水印文本的位置
        //                float x = 20; // 水印的X坐标
        //                float y = originalImage.Height - 20; // 水印的Y坐标

        //                // 在画布上绘制水印文本
        //                canvas.DrawText(watermarkText, x, y, paint);

        //                // 保存带有水印的图片
        //                string outputPath = Path.Combine(outputDirectory, Path.GetFileName(inputPath));
        //                using (var image = SKImage.FromBitmap(originalImage))
        //                using (var data = image.Encode(SKEncodedImageFormat.Jpeg, 100))
        //                using (var stream = File.OpenWrite(outputPath))
        //                {
        //                    data.SaveTo(stream);
        //                }

        //                Console.WriteLine($"处理完成: {inputPath} -> {outputPath}");
        //            }
        //        }

        //        // 删除原始图片
        //        File.Delete(inputPath);
        //        Console.WriteLine($"删除原始图片: {inputPath}");
        //    });
        //} 
        #endregion



        static async Task Main(string[] args)
        {
            string inputDirectory = "input_images"; // 输入图片目录
            string inputDirectorySingle = "input_images_single/Copy_1.jpg"; // 输入图片目录
            string outputDirectorySkia = "output_images_skia"; // SkiaSharp 输出目录
            string outputDirectorySkiaThreads = "output_images_skiaThreads"; // SkiaSharp 输出目录
            string outputDirectorygdiThreads = "output_images_gdiThreads"; // SkiaSharp 输出目录
            string outputDirectoryGdi = "output_images_gdi"; // GDI+ 输出目录

            // 创建输出目录
            Directory.CreateDirectory(outputDirectorySkia);
            Directory.CreateDirectory(outputDirectorySkiaThreads);
            Directory.CreateDirectory(outputDirectorygdiThreads);
            Directory.CreateDirectory(outputDirectoryGdi);

            #region 单张图片耗时
            var stopwatchSkiaSingle = Stopwatch.StartNew();
            ProcessSingleImageWithSkiaSharpAsync(inputDirectorySingle, outputDirectorySkiaThreads);
            stopwatchSkiaSingle.Stop();
            Console.WriteLine($"SkiaSharp 单张图片处理耗时: {stopwatchSkiaSingle.ElapsedMilliseconds} 毫秒 ; ");

            var stopwatchGDISingle = Stopwatch.StartNew();
            ProcessSingleImageWithGdiAsync(inputDirectorySingle, outputDirectorygdiThreads);
            stopwatchGDISingle.Stop();
            Console.WriteLine($"GDI+ 单张图片处理耗时: {stopwatchGDISingle.ElapsedMilliseconds} 毫秒 ; ");
            #endregion

            // 获取所有图片文件
            var imageFiles = Directory.GetFiles(inputDirectory, "*.jpg").Take(10000).ToArray();

            // 测试 SkiaSharpThreads 性能
            Console.WriteLine("开始 SkiaSharpThreads 性能测试...");
            int totalImages = imageFiles.Length;
            int threadCount = 16; // 16 个线程
            int imagesPerThread = totalImages / threadCount; // 每个线程处理的图片数量

            var stopwatchSkiaThreads = Stopwatch.StartNew();
            // 创建并启动线程
            Thread[] threads = new Thread[threadCount];
            for (int i = 0; i < threadCount; i++)
            {
                int startIndex = i * imagesPerThread;
                int endIndex = (i == threadCount - 1) ? totalImages : startIndex + imagesPerThread;

                threads[i] = new Thread(() => ProcessImages(imageFiles, startIndex, endIndex, outputDirectorySkia));
                threads[i].Start();
            }

            // 等待所有线程完成
            foreach (var thread in threads)
            {
                thread.Join();
            }
            stopwatchSkiaThreads.Stop();
            TimeSpan ts1 = Process.GetCurrentProcess().TotalProcessorTime;
            Console.WriteLine($"SkiaSharpThreads 处理完成，总耗时: {stopwatchSkiaThreads.ElapsedMilliseconds} 毫秒 ;  cpu耗时: {ts1}");

            #region GDI+ Threads
            Console.WriteLine("开始 gdi+ Threads 性能测试...");
            var stopwatchGDIThreads = Stopwatch.StartNew();
            // 创建并启动线程
            Thread[] threadsGDI = new Thread[threadCount];
            for (int i = 0; i < threadCount; i++)
            {
                int startIndex = i * imagesPerThread;
                int endIndex = (i == threadCount - 1) ? totalImages : startIndex + imagesPerThread;

                threadsGDI[i] = new Thread(() => ProcessImages1(imageFiles, startIndex, endIndex, outputDirectorygdiThreads));
                threadsGDI[i].Start();
            }

            // 等待所有线程完成
            foreach (var thread in threadsGDI)
            {
                thread.Join();
            }
            stopwatchGDIThreads.Stop();
            TimeSpan ts2 = Process.GetCurrentProcess().TotalProcessorTime;
            Console.WriteLine($"GDIThreads 处理完成，总耗时: {stopwatchGDIThreads.ElapsedMilliseconds} 毫秒 ;  cpu耗时: {ts2- ts1}");
            #endregion

            // 测试 GDI+ 性能
            Console.WriteLine("开始 GDI+ 性能测试...");
            var stopwatchGdi = Stopwatch.StartNew();
            await ProcessImagesWithGdiAsync(imageFiles, outputDirectoryGdi);
            stopwatchGdi.Stop();
            TimeSpan ts3 = Process.GetCurrentProcess().TotalProcessorTime;
            Console.WriteLine($"GDI+ 处理完成，总耗时: {stopwatchGdi.ElapsedMilliseconds} 毫秒 ;cpu耗时: {ts3 - ts2}");

            // 测试 SkiaSharp 性能
            Console.WriteLine("开始 SkiaSharp 性能测试...");
            var stopwatchSkia = Stopwatch.StartNew();
            await ProcessImagesWithSkiaSharpAsync(imageFiles, outputDirectorySkia);
            stopwatchSkia.Stop();
            TimeSpan ts4 = Process.GetCurrentProcess().TotalProcessorTime;
            Console.WriteLine($"SkiaSharp 处理完成，总耗时: {stopwatchSkia.ElapsedMilliseconds} 毫秒   ;cpu耗时: {ts4 - ts3}");

            // 输出性能对比结果
            Console.WriteLine("性能对比结果：");
            Console.WriteLine($"SkiaSharpThreads 总耗时: {stopwatchSkiaThreads.ElapsedMilliseconds} 毫秒");
            Console.WriteLine($"SkiaSharp 总耗时: {stopwatchSkia.ElapsedMilliseconds} 毫秒");
            Console.WriteLine($"GDI+ 总耗时: {stopwatchGdi.ElapsedMilliseconds} 毫秒");


        }


        static void ProcessImages(string[] imageFiles, int startIndex, int endIndex, string outputDirectory)
        {
            for (int i = startIndex; i < endIndex; i++)
            {
                string inputPath = imageFiles[i];
                ProcessSingleImageWithSkiaSharpAsync(inputPath, outputDirectory);
            }
        }
        static void ProcessImages1(string[] imageFiles, int startIndex, int endIndex, string outputDirectory)
        {
            for (int i = startIndex; i < endIndex; i++)
            {
                string inputPath = imageFiles[i];
                ProcessSingleImageWithGdiAsync(inputPath, outputDirectory);
            }
        }

        // 使用 SkiaSharp 异步处理图片
        static async Task ProcessImagesWithSkiaSharpAsync(string[] imageFiles, string outputDirectory)
        {
            var semaphore = new SemaphoreSlim(Environment.ProcessorCount * 2);

            var tasks = imageFiles.Select(async imageFile =>
            {
                await semaphore.WaitAsync();
                try
                {
                    ProcessSingleImageWithSkiaSharpAsync(imageFile, outputDirectory);
                }
                finally
                {
                    semaphore.Release();
                }
            });

            await Task.WhenAll(tasks);
        }

        // 使用 SkiaSharp 处理单张图片
        static void ProcessSingleImageWithSkiaSharpAsync(string inputPath, string outputDirectory)
        {
            // 加载原始图片
            using (var originalImage = SKBitmap.Decode(inputPath))
            {
                // 创建一个画布
                using (var canvas = new SKCanvas(originalImage))
                {
                    // 设置水印文本
                    string watermarkText = $"Watermark {Path.GetFileName(inputPath)}";

                    // 创建画笔
                    var paint = new SKPaint
                    {
                        Color = SKColors.White.WithAlpha(128), // 设置颜色和透明度
                        TextSize = 48, // 设置字体大小
                        IsAntialias = true, // 启用抗锯齿
                        Typeface = SKTypeface.FromFamilyName("Arial", SKFontStyle.Bold) // 设置字体
                    };

                    // 计算水印文本的位置
                    float x = 20; // 水印的X坐标
                    float y = originalImage.Height - 20; // 水印的Y坐标

                    // 在画布上绘制水印文本
                    canvas.DrawText(watermarkText, x, y, paint);

                    // 保存带有水印的图片
                    string outputPath = Path.Combine(outputDirectory, Path.GetFileName(inputPath));
                    using (var image = SKImage.FromBitmap(originalImage))
                    using (var data = image.Encode(SKEncodedImageFormat.Jpeg, 100))
                    using (var stream = File.OpenWrite(outputPath))
                    {
                        data.SaveTo(stream);
                    }
                }
            }
        }

        // 使用 GDI+ 异步处理图片
        static async Task ProcessImagesWithGdiAsync(string[] imageFiles, string outputDirectory)
        {
            var semaphore = new SemaphoreSlim(Environment.ProcessorCount * 2);

            var tasks = imageFiles.Select(async imageFile =>
            {
                await semaphore.WaitAsync();
                try
                {
                    ProcessSingleImageWithGdiAsync(imageFile, outputDirectory);
                }
                finally
                {
                    semaphore.Release();
                }
            });

            await Task.WhenAll(tasks);
        }

        static void ProcessSingleImageWithGdiAsync(string inputPath, string outputDirectory)
        {
            using (var originalImage = Image.FromFile(inputPath))
            using (var bitmap = new Bitmap(originalImage.Width, originalImage.Height, PixelFormat.Format32bppArgb))
            using (var graphics = Graphics.FromImage(bitmap))
            {
                graphics.DrawImage(originalImage, 0, 0, originalImage.Width, originalImage.Height);

                // 设置水印文本
                string watermarkText = $"Watermark {Path.GetFileName(inputPath)}";

                // 创建字体和画笔
                var font = new Font("Arial", 48, FontStyle.Bold);
                var brush = new SolidBrush(Color.FromArgb(128, 255, 255, 255));

                // 计算水印文本的位置
                float x = 20; // 水印的X坐标
                float y = bitmap.Height - 70; // 水印的Y坐标

                // 在画布上绘制水印文本
                graphics.DrawString(watermarkText, font, brush, x, y);

                // 保存带有水印的图片
                string outputPath = Path.Combine(outputDirectory, Path.GetFileName(inputPath));
                bitmap.Save(outputPath);

                // 释放字体和画笔
                font.Dispose();
                brush.Dispose();
            }
        }
    }
}
